/*
 * Copyright 2008 Carnegie Mellon University
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *  
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, 
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package edu.cmu.lti.sepia.data.db;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import edu.cmu.lti.sepia.infra.system.model.FilePermission;

/**
 * 
 * Manages FilePermission object in a DB.
 *
 * @see FilePermission
 * @author Hideki Shima
 *
 */
public class FilePermissisonDAO {

  public static void addFilePermissison( SQL sql, int fildId, FilePermission permission ) throws SQLException  {
    if (permission==null || permission.size()==0) {
      return;
    }
    String query = Query.generate( Query.ADD_FILE_PERMISSION, "" );

    PreparedStatement ps = sql.getConnection().prepareStatement(query);
    for (int taskdId : permission) {
      ps.setInt(1, fildId);
      ps.setInt(2, taskdId);
      sql.execute(ps);
    }
    ps.close();
  }
  
  public static void updateFilePermissison( SQL sql, int fildId, FilePermission permission ) throws SQLException {
    //delete and add
    deleteFilePermissison(sql, fildId);
    addFilePermissison(sql, fildId, permission);
  }
  
  public static void deleteFilePermissison( SQL sql, int fileId ) throws SQLException {
    String query = Query.generate( Query.DELETE_FILE_PERMISSION, "" );
    PreparedStatement ps = sql.getConnection().prepareStatement(query);
    ps.setInt(1, fileId);
    sql.execute(ps);
    ps.close();
  }
  
  public static FilePermission findByFileId( SQL sql, int fileId ) 
    throws SQLException {
    List<FilePermission> permissions = findByFileAndTaskId(sql, fileId, -1);
    if ( permissions.size()==1 ) {
      return findByFileAndTaskId(sql, fileId, -1).get(0);
    } else {
      return null;
    }
  }
  
  public static List<FilePermission> findByTaskId( SQL sql, int taskId )
    throws SQLException {
    return findByFileAndTaskId(sql, -1, taskId);
  }
  
  public static List<FilePermission> findByFileAndTaskId( SQL sql, int fileId, int taskId ) 
  throws SQLException {
    Map<Integer,FilePermission> map = findByFileAndTaskIdInMap(sql, fileId, taskId);
    return new ArrayList<FilePermission>(map.values());
  }
  
  public static Map<Integer,FilePermission> findByFileAndTaskIdInMap( SQL sql, int fileId, int taskId ) 
    throws SQLException {
    String query = null;
    if (fileId!=-1 && taskId!=-1) {
      query = Query.generate( Query.FIND_FILE_PERMISSION_BY_FILETASK, "" );
    } else if (fileId!=-1 && taskId==-1) {
      query = Query.generate( Query.FIND_FILE_PERMISSION_BY_FILE, "" );
    } else if (fileId==-1 && taskId!=-1) {
      query = Query.generate( Query.FIND_FILE_PERMISSION_BY_TASK, "" );
    } else {
      return null;
    }
    
    PreparedStatement ps = sql.getConnection().prepareStatement(query);
    if (fileId!=-1 && taskId!=-1) {
      ps.setInt(1, fileId);
      ps.setInt(2, taskId);
    } else if (fileId!=-1 && taskId==-1) {
      ps.setInt(1, fileId);
    } else if (fileId==-1 && taskId!=-1) {
      ps.setInt(1, taskId);
    }

    Map<Integer,FilePermission> map = new LinkedHashMap<Integer,FilePermission>();
    
    ResultSet rs = sql.executeSelect(ps);
   
    while ( rs.next() ) {
      int permittedFileId = rs.getInt(1);
      int permittedTaskId = rs.getInt(2);
      
      FilePermission fp = map.get(permittedFileId);
      if ( fp==null ) {
        fp = new FilePermission(permittedFileId);
      }
      fp.add(permittedTaskId);
      map.put(permittedFileId, fp);
    }
    rs.close();
    ps.close();
    
    return map;
  }
  
}
